package com.maimang.platform.dsp.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.maimang.platform.common.utils.DateUtils;
import com.maimang.platform.dsp.constant.AdvertiserApi;
import com.maimang.platform.dsp.entity.AdvertiserData;
import com.maimang.platform.dsp.entity.AdvertiserIds;
import com.maimang.platform.dsp.enums.StatType;
import com.maimang.platform.dsp.enums.TimeGranularity;
import com.maimang.platform.dsp.mapper.AdvertiserDataMapper;
import com.maimang.platform.dsp.mapper.AdvertiserIdsMapper;
import com.maimang.platform.dsp.service.AccessTokenService;
import com.maimang.platform.dsp.service.AdvertiserDataService;
import com.maimang.platform.dsp.utils.ApiService;
import com.maimang.platform.lang.ConvertUtils;
import com.maimang.platform.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;

/**
 * @author Rocky
 * @version 1.0.0
 * @classname AdvertiserDataServiceImpl
 * @description <br>广告主数据服务层实现类</br>
 * @date 2019-08-13 15:35:11
 * @email jintaozhao@qq.com
 */
@Service
public class AdvertiserDataServiceImpl implements AdvertiserDataService {

	@Autowired
	private AdvertiserDataMapper advertiserDataMapper;

	@Autowired
	private AdvertiserIdsMapper advertiserIdsMapper;

	@Autowired
	private ApiService apiService;

	@Autowired
	private AccessTokenService accessTokenService;

	/**
	 * 查询广告主数据信息
	 *
	 * @param pkId 广告主数据ID
	 * @return 广告主数据信息
	 */
	@Override
	public AdvertiserData selectAdvertiserDataById(Integer pkId) {
		return advertiserDataMapper.selectAdvertiserDataById(pkId);
	}

	/**
	 * 查询广告主数据列表
	 *
	 * @param advertiserData 广告主数据信息
	 * @return 广告主数据集合
	 */
	@Override
	public List<AdvertiserData> selectAdvertiserDataList(AdvertiserData advertiserData) {
		return advertiserDataMapper.selectAdvertiserDataList(advertiserData);
	}

	/**
	 * 查询广告主信息列表
	 *
	 * @param params 查询参数
	 * @return 广告主列表（id, name, company, create_time)
	 */
	@Override
	public List<Map> selectAdvertiserList(Map params) {
		return null;
	}

	/**
	 * 新增广告主数据
	 *
	 * @param advertiserData 广告主数据信息
	 * @return 结果
	 */
	@Override
	public int insertAdvertiserData(AdvertiserData advertiserData) {
		return advertiserDataMapper.insertAdvertiserData(advertiserData);
	}

	/**
	 * 修改广告主数据
	 *
	 * @param advertiserData 广告主数据信息
	 * @return 结果
	 */
	@Override
	public int updateAdvertiserData(AdvertiserData advertiserData) {
		return advertiserDataMapper.updateAdvertiserData(advertiserData);
	}

	/**
	 * 删除广告主数据对象
	 *
	 * @param ids 需要删除的数据ID
	 * @return 结果
	 */
	@Override
	public int deleteAdvertiserDataByIds(String ids) {
		return advertiserDataMapper.deleteAdvertiserDataByIds(ConvertUtils.toStrArray(ids));
	}

	/**
	 * 清空所有记录
	 *
	 * @return
	 */
	@Override
	public int deleteByAdvertiserId(String advertiserId) {
		return advertiserDataMapper.deleteByAdvertiserId(advertiserId);
	}

	/**
	 * @param advertiserId 代理商广告主id
	 * @param recentlyDays 最近多少天的数据，最大30
	 * @return
	 */
	@Override
	public void syncAdvertiserData(Long advertiserId, int recentlyDays) {
		AdvertiserIds ids = new AdvertiserIds();
		ids.setPId(advertiserId);
		List<AdvertiserIds> idsList = advertiserIdsMapper.selectAdvertiserIdsList(ids);
		String today = DateUtils.getToday();
		String startDate = DateUtils.getBeforeDayString(today, recentlyDays);

		double total = idsList.size();
		int pageSize = 2000;
		double totalPage = Math.ceil(total / pageSize);
		for (int i = 0; i < totalPage; i++) {
			int beginIndex = i * pageSize;
			int endIndex = (int) Math.min((i + 1) * pageSize, total);

			Executors.newCachedThreadPool().execute(() -> {
				List<AdvertiserIds> advertiserIdsList = idsList.subList(beginIndex, endIndex);

				for (int j = 0; j < advertiserIdsList.size(); j++) {
					AdvertiserIds advertiserIds = advertiserIdsList.get(j);
					syncData(advertiserIds.getId().toString(), startDate, today);
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}

	/**
	 * 批量同步广告主数据
	 *
	 * @param ids          广告主id列表
	 * @param recentlyDays 最近多少天的数据，最大30
	 * @return
	 */
	@Override
	public int syncAdvertiserDataByIds(String ids, int recentlyDays) {
		if (StringUtils.isEmpty(ids))
			return 0;
		String[] idList = ids.split(",");
		String endDate = DateUtils.getDate();
		String startDate = DateUtils.getBeforeDayString(endDate, recentlyDays);
		for (int i = 0; i < idList.length; i++) {
			String advertiserId = idList[i];
			syncData(advertiserId, startDate, endDate);
		}

		return idList.length;
	}

	/**
	 * @param advertiserId 广告主id
	 * @param startDate    开始日期
	 * @param endDate      结束日期
	 */
	private void syncData(String advertiserId, String startDate, String endDate) {
		String[] groupBy = StatType.STAT_GROUP_BY_FIELD_STAT_TIME.getValue().split(",");
		String timeGranularity = TimeGranularity.STAT_TIME_GRANULARITY_DAILY.getValue();
		int page = 1;
		int pageSize = 999;
		handleRemoteData(advertiserId, startDate, endDate, groupBy, timeGranularity, page, pageSize);
	}

	/**
	 * 处理远程请求的广告主数据返回结果集
	 *
	 * @param advertiserId
	 * @param startDate
	 * @param endDate
	 * @param groupBy
	 * @param timeGranularity
	 * @param page
	 * @param pageSize
	 */
	private void handleRemoteData(String advertiserId, String startDate, String endDate, String[] groupBy, String timeGranularity, int page, int pageSize) {
		JSONObject result = getAdvertiserDataList(advertiserId, startDate, endDate, groupBy, timeGranularity, page, pageSize);
		if (result.getIntValue("code") == 0) {
			JSONObject pageInfo = result.getJSONObject("data").getJSONObject("page_info");
			JSONArray dataList = result.getJSONObject("data").getJSONArray("list");
			List<AdvertiserData> advertiserDataList = dataList.toJavaList(AdvertiserData.class);
			for (int i = 0; i < advertiserDataList.size(); i++) {
				AdvertiserData advertiserData = advertiserDataList.get(i);
				advertiserData.setGroupBy(StringUtils.join(groupBy, ","));
				advertiserData.setTimeGranularity(timeGranularity);
				if (StringUtils.isNotNull(advertiserData.getAdvertiserId()) && StringUtils.isNotEmpty(advertiserData.getStatDatetime())) {
					// 删除原来的旧数据，减少查询
					advertiserDataMapper.deleteAdvertiserDataById(advertiserData.getAdvertiserId(), advertiserData.getStatDatetime());
					// 重新插入新的数据
					advertiserDataMapper.insertAdvertiserData(advertiserData);
				}
			}
			int total_number = pageInfo.getIntValue("total_number");
			pageSize = pageInfo.getIntValue("page_size");
			page = pageInfo.getIntValue("page");
			if (total_number > pageSize * page) {
				page++;
				handleRemoteData(advertiserId, startDate, endDate, groupBy, timeGranularity, page, pageSize);
			}
		}
	}

	/**
	 * 获取广告主基本数据，包括花费、点击量、点击单价等
	 *
	 * @param advertiserId    广告主id
	 * @param startDate       开始日期
	 * @param endDate         结束日期
	 * @param groupBy         分组条件
	 * @param timeGranularity 时间粒度
	 * @param page            页码 默认值: 1,取值范围: ≥ 0
	 * @param pageSize        每页数据量,默认值: 20,取值范围: 1-1000
	 * @return
	 */
	@Override
	public JSONObject getAdvertiserDataList(String advertiserId, String startDate, String endDate, String[] groupBy, String timeGranularity, int page, int pageSize) {
		String accessToken = accessTokenService.accessToken();
		if (StringUtils.isEmpty(accessToken))
			return null;

		Map params = new HashMap();
		params.put("advertiser_id", advertiserId);
		params.put("start_date", startDate);
		params.put("end_date", endDate);
		if (StringUtils.isNotEmpty(groupBy)) {
			params.put("group_by", groupBy);
		}
		if (StringUtils.isNotEmpty(timeGranularity)) {
			params.put("time_granularity", timeGranularity);
		}
		if (page >= 0) {
			params.put("page", page);
		}
		if (pageSize >= 1) {
			params.put("page_size", pageSize);
		}
		JSONObject result = apiService.sendGet(AdvertiserApi.REPORT_ADVERTISER, accessToken, params);

		return result;
	}

}